/*
 * Copyright (C) 2021 HiHope Open Source Organization .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 *
 * limitations under the License.
 */
#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_watchdog.h"
#include "iot_pwm.h"
#include "hi_io.h"
#include "hi_adc.h"
#include "hi_time.h"
#include "icm.h"
#include "ssd1306.h"
#include "iot_errno.h"
#include "io_oled_demo.h"

//#define     IOT_GPIO_LED_SLEEP  2
//#define     IOT_GPIO_LED_RUN    7
#define     IOT_GPIO_KEY2       2
#define     IOT_GPIO_KEY3       10
#define     IOT_PWM_PORT_PWM2   2
#define     IOT_PWM_BEEP        5

#define     CLK_160M            160000000
#define     OLED_I2C_BAUDRATE   400*1000
#define     IOT_I2C_IDX_0          0

int g_modeStatus_pre = 0xff;
int g_modeStatus = OTHER_TEST;
int key_up = 1;
extern int g_netId;
extern int g_hotspotStarted;

void testMOde (void) {

    printf("!!g_modeStatus_pre is %d g_modeStatus is %d\r\n", g_modeStatus_pre, g_modeStatus);

    if(g_modeStatus_pre != g_modeStatus)
    {
        g_modeStatus_pre = g_modeStatus;

        switch (g_modeStatus) {
            case OTHER_TEST:
                printf("OTHER_TEST test mode is %d\r\n", g_modeStatus);
                Ssd1306TestTask(NULL);
                StartPWMBeerTask();

                //IoTPwmStart(2, 50, 4000);
                break;
            case ATH_TEST:
                printf("ATH_TEST test mode is %d\r\n", g_modeStatus);

                IoTPwmStop(2);

                Aht20TestTask(NULL);
                Ltr553Test();
                SixAxisTask();

                break;
            case AP_TEST:
                printf("AP_TEST test mode is %d\r\n", g_modeStatus);
                
                StopHotspot();

                WifiHotspotTask(NULL);
                break;
            case NFC_TEST:
                printf("NFC_TEST test mode is %d\r\n", g_modeStatus);
                
                nfcTask();
                break;
            case UNI_TEST:
                printf("UNI_TEST test mode is %d\r\n", g_modeStatus);
                UartDemo_Task();
                break;
            default:
                break;
        }
    }
}

static void OnButtonPressedKey2(char *arg)
{
    (void) arg;

    int nextState = OTHER_TEST;
    
    IotGpioValue key2_value = IOT_GPIO_VALUE0;
    IoTGpioGetInputVal(IOT_GPIO_KEY2, &key2_value);
    printf("_____>>>>> %s %d \r\n", __FILE__, __LINE__);
    usleep(500*1000);
    printf("_____>>>>> %s %d \r\n", __FILE__, __LINE__);
    printf("____>>>>>>> key2_value is %d \r\n", key2_value);

    if(key2_value == 0) {
        printf("!!g_modeStatus is %d\r\n", g_modeStatus);
        switch (g_modeStatus) {
            case OTHER_TEST:
                nextState = ATH_TEST;
                break;
            case ATH_TEST:
                nextState = AP_TEST;
                break;
            case AP_TEST:
                nextState = NFC_TEST;
                break;
            case NFC_TEST:
                nextState = UNI_TEST;
                break;
            case UNI_TEST:
                nextState = OTHER_TEST;
                break;
            default:
                break;
        }

        g_modeStatus = nextState;
    }
}

static void OnButtonPressedKey3(char *arg)
{
    (void) arg;

    int preState = OTHER_TEST;
    IotGpioValue key3_value = IOT_GPIO_VALUE0;
    IoTGpioGetInputVal(IOT_GPIO_KEY3, &key3_value);
    printf("_____>>>>> %s %d \r\n", __FILE__, __LINE__);
    usleep(500*1000);
    printf("____>>>>>>> key3_value is %d \r\n", key3_value);
    printf("_____>>>>> %s %d \r\n", __FILE__, __LINE__);

    if(key3_value == 0) {
        switch (g_modeStatus) {
            case OTHER_TEST:
                preState = UNI_TEST;
                break;
            case ATH_TEST:
                preState = OTHER_TEST;
                break;
            case AP_TEST:
                preState = ATH_TEST;
                break;
            case NFC_TEST:
                preState = AP_TEST;
                break;
            case UNI_TEST:
                preState = NFC_TEST;
                break;
            default:
                break;
        }

        g_modeStatus = preState;
    }

}


static void *GpioTask(const char *arg)
{
    (void)arg;
    ssd1306_Fill(White);
    ssd1306_UpdateScreen();
//    IoTPwmStart(IOT_PWM_PORT_PWM2, 50, 4000);
//    osDelay(100);
//    IoTPwmStop(IOT_PWM_PORT_PWM2);

    while(1) {
        testMOde();
        osDelay(10);
    }

}

static void StartGpioTask(void)
{
    osThreadAttr_t attr;


    IoTGpioInit(IOT_GPIO_KEY2);
    hi_io_set_func(IOT_GPIO_KEY2, 0);//HI_IO_FUNC_GPIO_8_GPIO == 0
    IoTGpioSetDir(IOT_GPIO_KEY2, IOT_GPIO_DIR_IN);
    hi_io_set_pull(IOT_GPIO_KEY2, 1);
    IoTGpioRegisterIsrFunc(IOT_GPIO_KEY2, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW,
        OnButtonPressedKey2, NULL);

    IoTGpioInit(IOT_GPIO_KEY3);
    hi_io_set_func(IOT_GPIO_KEY3, 0);//HI_IO_FUNC_GPIO_8_GPIO == 0
    IoTGpioSetDir(IOT_GPIO_KEY3, IOT_GPIO_DIR_IN);
    hi_io_set_pull(IOT_GPIO_KEY3, 1);
    IoTGpioRegisterIsrFunc(IOT_GPIO_KEY3, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW,
        OnButtonPressedKey3, NULL);


    IoTGpioInit(IOT_PWM_BEEP);
    hi_io_set_func(IOT_PWM_BEEP, 5);
    IoTGpioSetDir(IOT_PWM_BEEP, IOT_GPIO_DIR_OUT);
    IoTPwmInit(IOT_PWM_PORT_PWM2);
    IoTPwmStop(IOT_PWM_PORT_PWM2);

    unsigned int retval = 0;

    retval = IoTGpioInit(13);
    if (retval != IOT_SUCCESS) {
        printf("IoTGpioInit(13) failed, %0X!\n", retval);
        return retval;
    }    
    retval = IoTGpioInit(14);
    if (retval != IOT_SUCCESS) {
        printf("IoTGpioInit(14) failed, %0X!\n", retval);
        return retval;
    }
    retval = hi_io_set_func(13, 6);
    if (retval != IOT_SUCCESS) {
        printf("hi_io_set_func(13) failed, %0X!\n", retval);
        return retval;
    }
    retval = hi_io_set_func(14, 6);
    if (retval != IOT_SUCCESS) {
        printf("hi_io_set_func(14) failed, %0X!\n", retval);
        return retval;
    }     

    int ret = IoTI2cInit(IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);
    ssd1306_Init();
    IoTWatchDogDisable();

    attr.name = "GpioTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024 * 10;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)GpioTask, NULL, &attr) == NULL) {
        printf("[GpioDemo] Falied to create GpioTask!\n");
    }
}

APP_FEATURE_INIT(StartGpioTask);
